package simplescenegraph;

import java.util.ArrayList;
import java.util.Iterator;

import simplescenegraph.math.Vector3f;

public class GroupNode extends Node {
	
	private ArrayList<Node> childNodes = new ArrayList<Node>();
	
	private BoundingVolume worldBound = null;
	
	public void updateGeometricState(float time, boolean initiator) {
		Iterator<Node> it;
		
		super.updateGeometricState(time, initiator);
		
		if (!updated) {
			it = childNodes.iterator();
			while (it.hasNext()) {
				it.next().updateGeometricState(time, initiator);
			}
		}
	}
	
	/**
	 * Updates world bounds recursively from the bottom-up traversal of the tree
	 * structure.
	 * 
	 */
	// TODO: Change it in order to be called only once even when more than one
	// different sub-branch is updated.
	protected void updateWorldBound() {
		BoundingVolume b0;
		Iterator<Node> it;
		
		if (!childNodes.isEmpty()) {
			worldBound = null;
			it = childNodes.iterator();
			while (it.hasNext()) {
				b0 = it.next().getWorldBound();
				if (b0 != null) {
					if (worldBound == null)
						worldBound = b0.copy();
					else
						worldBound.merge(b0);
				}
			}
		}
	}
	
	public BoundingVolume getWorldBound() {
		return worldBound;
	}
	
	public boolean onDraw(Renderer r0) {
		Iterator<Node> it;
		if (super.onDraw(r0)) {
			if (!childNodes.isEmpty()) {
				it = childNodes.iterator();
				while (it.hasNext())
					it.next().onDraw(r0);
			}
			return true;
		}
		return false;
	}
	
	public void addChildNode(Node n0) {
		if (n0 != null) {
			childNodes.add(n0);
			n0.parent = this;
			updated = true;
		}
	}
	
	public void removeChildNode(Node n0) {
		if (n0 != null && childNodes.remove(n0)) {
			n0.parent = null;
			updated = true;
		}
	}
	
	public void removeChildNode(int i0) {
		Node n0;
		if ((n0 = childNodes.remove(i0)) != null) {
			n0.parent = this;
			updated = true;
		}
	}
	
	public Node getChildNode(int i0) {
		return childNodes.get(i0);
	}
	
	public int childCount() {
		return childNodes.size();
	}
	
	public void rotateAxis(float a0, Vector3f a1) {
		super.rotateAxis(a0, a1);
		updateChildren();
	}
	
	public void rotateX(float a0) {
		super.rotateX(a0);
		updateChildren();
	}
	
	public void rotateY(float a0) {
		super.rotateY(a0);
		updateChildren();
	}
	
	public void rotateZ(float a0) {
		super.rotateZ(a0);
		updateChildren();
	}
	
	public void scale(float f0, float f1, float f2) {
		super.scale(f0, f1, f2);
		updateChildren();
	}
	
	public void translate(float f0, float f1, float f2) {
		super.translate(f0, f1, f2);
		updateChildren();
	}
	
	private void updateChildren() {
		Iterator<Node> it0 = childNodes.iterator();
		while (it0.hasNext()) {
			it0.next().updated = true;
		}
	}
	
}
